use std::collections::HashMap;

use common_base::serde::{self, Serialize};

use crate::data::{DatasetOwner, RowsetOwner};

use super::{metadata::MetadataBase, Metadata};

#[derive(Debug, Clone)]
// #[derive(Serialize)]
// #[serde(crate = "self::serde")]
// #[serde(rename_all = "camelCase")]
pub struct DctMetadata {
    pub(crate) base: MetadataBase,
    pub(crate) fkey_dct_metadatas: Vec<String>,
    pub(crate) rlgl_dct_map: HashMap<String, String>,
    pub(crate) rlgl_do_map: HashMap<String, String>,
    pub(crate) acjgsz: Option<DatasetOwner>,
    pub(crate) sys_dct_cst: Option<DatasetOwner>,
    // deprecated
    // pub(crate) ref_dct_id: Option<String>,
}

impl Into<Metadata> for DctMetadata {
    fn into(self) -> Metadata {
        Metadata::Dct(self)
    }
}

impl DctMetadata {
    pub const SYS_DICTS: &'static str = "SYS_DICTS";
    pub const MAIN_DO_META_DATA: &'static str = "mainDoMetaData";

    pub fn new(dct_id: &str, rowset: RowsetOwner) -> Self {
        Self {
            base: MetadataBase::new(dct_id, rowset),
            fkey_dct_metadatas: Default::default(),
            rlgl_dct_map: Default::default(),
            rlgl_do_map: Default::default(),
            acjgsz: None,
            sys_dct_cst: None,
            // ref_dct_id: Default::default(),
        }
    }

    pub fn metadata_base_mut(&mut self) -> &mut MetadataBase {
        &mut self.base
    }
}

impl DctMetadata {
    pub fn get_object_id(&self) -> &str {
        &self.base.object_id
    }

    pub fn set_do_metadata(&mut self, do_metadata: Metadata) {
        self.base
            .self_rowset
            .put_object(Self::MAIN_DO_META_DATA, do_metadata.into());
    }

    pub fn get_do_metadta(&self) -> Option<&Metadata> {
        self.base
            .self_rowset
            .get_object(Self::MAIN_DO_META_DATA)
            .map(|x| {
                x.as_object()
                    .unwrap()
                    .as_any()
                    .downcast_ref::<Metadata>()
                    .unwrap()
            })
    }

    pub fn set_fkey_dct_metadatas(&mut self, fkey_dct_metadatas: Vec<String>) {
        self.fkey_dct_metadatas = fkey_dct_metadatas;
    }

    pub fn insert_dataset(&mut self, key: &str, dataset: DatasetOwner) {
        self.base.self_rowset.insert_dataset(key, dataset);
    }

    pub fn get_dataset(&self, key: &str) -> Option<&DatasetOwner> {
        self.base.self_rowset.get_dataset(key)
    }

    pub fn set_rlgl_dct_map(&mut self, rlgl_dct_map: HashMap<String, String>) {
        self.rlgl_dct_map = rlgl_dct_map;
    }
    pub fn set_rlgl_do_map(&mut self, rlgl_do_map: HashMap<String, String>) {
        self.rlgl_do_map = rlgl_do_map;
    }

    pub fn set_acjgsz(&mut self, acjgsz: DatasetOwner) {
        self.acjgsz = Some(acjgsz);
    }

    pub fn set_sys_dct_cst(&mut self, sys_dct_cst: DatasetOwner) {
        self.sys_dct_cst = Some(sys_dct_cst);
    }
}

// Deprecated
// impl DctMetadata {
//     pub fn set_ref_dct_id(&mut self, ref_dct_id: String) {
//         self.ref_dct_id = Some(ref_dct_id);
//     }
//     pub fn get_ref_dct_id(&self) -> Option<&String> {
//         self.ref_dct_id.as_ref()
//     }
// }
